package io.github.zhx666666.word;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: zhaohaoxin
 * @Date: 2023-10-17-17:53
 */
public class MergeMultiWord {

    public static void main(String[] args) {
        List<String> fileNameList = new ArrayList<>();
        fileNameList.add("H:\\aa.docx");
        fileNameList.add("H:\\bb.docx");
        mergeMultiWord("H:\\cc11asd.docx",fileNameList);
    }



    public static void mergeMultiWord(String mergeFileName, List<String> fileNames){
        try {
// List<File> srcfile = new ArrayList<>();
// for( int i = 0; i < fileNames.size(); i++ ){
// File file1 = new File( fileNames.get(i));
// srcfile.add(file1);
// }
            OutputStream dest = new FileOutputStream( mergeFileName );
            ArrayList<XWPFDocument> documentList = new ArrayList<>();
            XWPFDocument doc = null;
            for( int i = 0; i < fileNames.size(); i++ ) {
                FileInputStream in = new FileInputStream( fileNames.get(i) );
                OPCPackage open = OPCPackage.open( in );
                XWPFDocument document = new XWPFDocument( open );
                documentList.add( document );
            }
            for( int i = 0; i < documentList.size(); i++ ) {
                doc = documentList.get( 0 );
                if( i != 0 ) {
// 分页
                    documentList.get( i ).createParagraph().setPageBreak( true );
                    appendBody( doc, documentList.get( i ) );
                }
            }
// 分页
            doc.createParagraph().setPageBreak( true );
            doc.write( dest );
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }

    public static void FileCopy(String[] inPath,String outPath) {
        File newFile = new File( outPath);
        List<File> srcfile = new ArrayList<>();
        for (String s : inPath) {
            File file = new File(s);
            srcfile.add( file );
        }
        try {
            OutputStream dest = new FileOutputStream( newFile );
            ArrayList<XWPFDocument> documentList = new ArrayList<>();
            XWPFDocument doc = null;
            FileInputStream in=null;
            for( int i = 0; i < srcfile.size(); i++ ) {
                in = new FileInputStream( srcfile.get( i ).getPath() );
                OPCPackage open = OPCPackage.open( in );
                XWPFDocument document = new XWPFDocument( open );
                documentList.add( document );
            }
            in.close();
            for( int i = 0; i < documentList.size(); i++ ) {
                doc = documentList.get( 0 );
                if( i != 0 ) {
// 分页
                    documentList.get( i ).createParagraph().setPageBreak( true );
                    appendBody( doc, documentList.get( i ) );
                }
            }
// 分页
            doc.createParagraph().setPageBreak( true );
            doc.write( dest );

        } catch( Exception e ) {
            e.printStackTrace();
        }
    }



    public static void appendBody( XWPFDocument src, XWPFDocument append ) throws Exception {
        CTBody src1Body = src.getDocument().getBody();
        CTBody src2Body = append.getDocument().getBody();
        List<XWPFPictureData> allPictures = append.getAllPictures();
// 记录图片合并前及合并后的ID
        Map<String, String> map = new HashMap<>();
        for( XWPFPictureData picture : allPictures ) {
            String before = append.getRelationId( picture );
// 将原文档中的图片加入到目标文档中
            String after = src.addPictureData( picture.getData(), Document.PICTURE_TYPE_PNG );
            map.put( before, after );
        }
        appendBody( src1Body, src2Body, map );
    }

    private static void appendBody( CTBody src, CTBody append, Map<String, String> map ) throws Exception {
        XmlOptions optionsOuter = new XmlOptions();
        optionsOuter.setSaveOuter();
        String appendString = append.xmlText( optionsOuter );
        String rgex = "<[\\s]*?w:sectPr[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?w:sectPr[\\s]*?>";
        appendString = appendString.replaceAll( rgex, "" );
// 去除分页符
        String srcString = src.xmlText().replaceAll( "<w:p><w:r><w:br w:type=\"page\"/></w:r></w:p>", "" ).replaceAll( "<w:r><w:br w:type=\"page\"/></w:r>", "" );
        String prefix = srcString.substring( 0, srcString.indexOf( ">" ) + 1 );
        String mainPart = srcString.substring( srcString.indexOf( ">" ) + 1, srcString.lastIndexOf( "<" ) );
        String sufix = srcString.substring( srcString.lastIndexOf( "<" ) );
        String addPart = appendString.substring( appendString.indexOf( ">" ) + 1, appendString.lastIndexOf( "<" ) );
        if( map != null && !map.isEmpty() ) {
// 对xml字符串中图片ID进行替换
            for( Map.Entry<String, String> set : map.entrySet() ) {
                addPart = addPart.replace( set.getKey(), set.getValue() );
            }
        }
// 将两个文档的xml内容进行拼接
        CTBody makeBody = CTBody.Factory.parse( prefix + mainPart + addPart + sufix );
        src.set( makeBody );
    }
}
